package com.ruoyi.car.service;

import com.alibaba.fastjson2.JSON;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.ruoyi.car.api.bo.WxSmsBo;
import com.ruoyi.car.utils.CodeUtil;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * 短信服务
 */
@Slf4j
@Service
public class SmsService {
    @Autowired
    private RedisCache redisCache;

    @Value("${sms.alibaba.accessKeyId}")
    private String accessKeyId;

    @Value("${sms.alibaba.accessKeySecret}")
    private String accessKeySecret;

    @Value("${sms.alibaba.signature}")
    private String signature;

    @Value("${sms.alibaba.templateCode}")
    private String templateCode;

    public void sendSms(WxSmsBo smsBo) {
        String phone = smsBo.getPhone();
        String redisKey = buildRedisKey(phone);
        if (redisCache.getCacheObject(redisKey) != null) {
            throw new ServiceException("该手机号验证码1分钟内只能发送一次哦");
        }
        String code = CodeUtil.getCapthCode();
        log.info("验证码：{}",code);
        //先保存redis缓存，当发送失败时管理员可以查看验证码
        redisCache.setCacheObject(redisKey, code, 1, TimeUnit.MINUTES);
        this.sendVerifyCodeMessage(phone, code);
    }

    private String buildRedisKey(String phone) {
        return "sms:" + phone;
    }

    /**
     * 校验验证码是否一致
     */
    public void checkCode(String phone,String code){
        String redisCode = redisCache.getCacheObject(buildRedisKey(phone));
        boolean check = code.equals(redisCode);
        if(!check){
            throw new ServiceException("验证码不正确");
        }
    }

    /**
     * 查询短信验证码
     * @param phone
     * @return
     */
    public String queryCode(String phone){
        return redisCache.getCacheObject(this.buildRedisKey(phone));
    }

    /**
     * 发送短信
     *
     * @param phoneNumbers 手机号
     * @param param        参数
     */
    private void sendVerifyCodeMessage(String phoneNumbers, String param) {
        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou",
                accessKeyId,
                accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);

        SendSmsRequest request = new SendSmsRequest();
        request.setSysRegionId("cn-hangzhou");
        request.setPhoneNumbers(phoneNumbers);
        request.setSignName(signature);
        request.setTemplateCode(templateCode);
        request.setTemplateParam("{\"code\":\"" + param + "\"}");
        try {
            SendSmsResponse response = client.getAcsResponse(request);
            log.info("短信发送返回信息:{}", JSON.toJSONString(response));
            if (!response.getCode().equals("OK")) {
                throw new ServiceException("短信发送失败，请及时联系管理员获取验证码");
            }
        } catch (ClientException e) {
            log.error("短信发送失败", e);
            throw new ServiceException("短信发送失败，请及时联系管理员获取验证码");
        }
    }
}
